using System;
using System.Collections.Generic;
using System.Configuration;
using System.Net.Mail;
using System.Text;
using System.Xml;
using Common.Utilities;
using Common.Utilities.Dispatcher;
using Workflows.Components.Communication.Properties;

namespace Workflows.Components.Communication
{
    /// <summary></summary>
    [Serializable]
    public class EmailComponent:WorkflowComponentBase
    {
        #region props & fields

        private EmailInstruction _Instruction;
        private EmailOutput _Output;
        /// <summary></summary>
        public string SmtpServer
        {
            get { return this._Instruction.SmtpServer; }
            set { this._Instruction.SmtpServer = value; }
        }
        /// <summary></summary>
        public string FromAddress
        {
            get { return this._Instruction.From; }
            set { this._Instruction.From = value; }
        }
        /// <summary></summary>
        public string ToAddresses
        {
            get { return this._Instruction.To; }
            set { this._Instruction.To = value; }
        }
        /// <summary></summary>
        public string CC
        {
            get{ return this._Instruction.CC;}
            set{ this._Instruction.CC = value;}
        }

        /// <summary></summary>
        public string Subject
        {
            get { return this._Instruction.Subject; }
            set { this._Instruction.Subject = value; }
        }
        /// <summary></summary>
        public string BodyTemplate
        {
            get { return this._Instruction.BodyTemplate; }
            set { this._Instruction.BodyTemplate = value; }
        }
        /// <summary></summary>
        public string[] Attachments
        {
            get { return this._Instruction.Attachments; }
            set { this._Instruction.Attachments = value; }
        }
        /// <summary></summary>
        public string UserName
        {
            get { return this._Instruction.UserName; }
            set { this._Instruction.UserName = value; }
        }
        /// <summary></summary>
        public string Password
        {
            get { return this._Instruction.Password; }
            set { this._Instruction.Password = value; }
        }
        /// <summary></summary>
        public bool RequireAuthentication
        {
            get { return this._Instruction.RequireAuthentication; }
            set { this._Instruction.RequireAuthentication = value; }
        }
        /// <summary></summary>
        public MailPriority Priority
        {
            get { return this._Instruction.Priority; }
            set { this._Instruction.Priority = value; }
        }

        public override InstructionBase Instruction
        {
            get { return this._Instruction; }
            set { this._Instruction = (EmailInstruction) value; }
        }

        public override ResultBase Output
        {
            get { return this._Output; }
            set { this._Output = (EmailOutput) value; }
        }

        /// <summary></summary>
        public bool UseOutlookClient
        {
            get
            {
                return this._Instruction.UseOutlookClient;
            }
            set
            {
                this._Instruction.UseOutlookClient = value;
            }
        }

        /// <summary></summary>
        public bool EnableSSL
        {
            get
            {
                return this._Instruction.EnableSSL;
            }
            set
            {
                this._Instruction.EnableSSL = value;
            }
        }

        /// <summary></summary>
        public Dictionary<string, string> BodyPlaceHolders
        {
            get
            {
                return this._Instruction.BodyPlaceHolders;
            }
            set
            {
                this._Instruction.BodyPlaceHolders = value;
            }
        }
        #endregion
        /// <summary></summary>
        public EmailComponent()
        {
            this.ComponentName = "Email";
            this.Description = "Send email message";
            this.ComponentIcon = Resources.mssvp_500;
            this.ComponentImage = Resources.letter;
            this.ComponentActivityType = WorkflowActivityType.SimpleActivity;
            this.ComponentCategory = WorkflowComponentCategory.Communication_Tasks.ToString();

            this._Instruction =
                new EmailInstruction(this.ComponentID, Guid.Empty, ConfigurationManager.AppSettings.Get("SmtpServer"),
                                     Environment.UserName + "@" + Environment.UserDomainName + ".com", string.Empty,
                                     string.Empty, "[Subject]", MailPriority.Normal, false,
                                     "li.xiaodong@DiscoveryLogic.com", "xiaodong", null,
                                     string.Empty, false, false, new Dictionary<string, string>());
            this._Output=new EmailOutput(this.ComponentID, Guid.Empty);
        }

        public override XmlNode Serialize(ref XmlDocument xDoc, ref XmlNode parentNode)
        {
            XmlNode xNode = base.Serialize(ref xDoc, ref parentNode);

            XmlDataUtil.UpdateAttribute(ref xDoc,xNode,"SmtpServer",this.SmtpServer);
            XmlDataUtil.UpdateAttribute(ref xDoc,xNode,"FromAddress",this.FromAddress);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ToAddresses", this.ToAddresses);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "CC",this.CC);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "Subject", this.Subject);
            XmlDataUtil.UpdateAttribute(ref xDoc,xNode,"Body",this.BodyTemplate);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "RequireAuthentication", this.RequireAuthentication.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "UserName", this.UserName);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "Password", this.Password);
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "Attachments", StringUtil.ToString(this.Attachments));
            XmlDataUtil.UpdateAttribute(ref xDoc,xNode,"Priority",((int)this.Priority).ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "UseOutlook", this.UseOutlookClient.ToString());
            XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "EnableSsl", this.EnableSSL.ToString());

            if (this.BodyPlaceHolders != null && this.BodyPlaceHolders.Count > 0)
            {
                XmlNode placeHolderRootNode = XmlDataUtil.AddElement(ref xDoc, xNode, "PlaceHolders");
                foreach (string placeHolderName in this.BodyPlaceHolders.Keys)
                {
                    XmlNode placeHolderNode = XmlDataUtil.AddElement(ref xDoc, placeHolderRootNode, "PlaceHolder");
                    XmlDataUtil.UpdateAttribute(ref xDoc, placeHolderNode, "Name", placeHolderName);
                    XmlDataUtil.UpdateAttribute(ref xDoc, placeHolderNode, "Value",
                                                this.BodyPlaceHolders[placeHolderName]);
                }
            }

            return xNode;
        }

        public override WorkflowComponentBase Instantiate(XmlNode xNode)
        {
            if (xNode.Attributes.GetNamedItem("Type").Value == this.GetType().FullName)
            {
                EmailComponent email = base.Instantiate(xNode) as EmailComponent;

                email.SmtpServer = xNode.Attributes.GetNamedItem("SmtpServer").Value;
                email.FromAddress = xNode.Attributes.GetNamedItem("FromAddress").Value;
                email.ToAddresses = XmlDataUtil.GetAttributeValue(xNode, "ToAddresses", "");
                email.CC = XmlDataUtil.GetAttributeValue(xNode, "CC", "");
                email.Subject = xNode.Attributes.GetNamedItem("Subject").Value;
                email.BodyTemplate = xNode.Attributes.GetNamedItem("Body").Value;
                email.RequireAuthentication = bool.Parse(xNode.Attributes.GetNamedItem("RequireAuthentication").Value);
                email.UserName = xNode.Attributes.GetNamedItem("UserName").Value;
                email.Password = xNode.Attributes.GetNamedItem("Password").Value;
                email.Attachments = StringUtil.Split(xNode.Attributes.GetNamedItem("Attachments").Value);
                email.Priority = (MailPriority) int.Parse(xNode.Attributes.GetNamedItem("Priority").Value);
                email.UseOutlookClient = bool.Parse(xNode.Attributes.GetNamedItem("UseOutlook").Value);
                email.EnableSSL = bool.Parse(xNode.Attributes.GetNamedItem("EnableSsl").Value);

                XmlNodeList placeHolderNodes = xNode.SelectNodes("PlaceHolders/PlaceHolder");
                if (placeHolderNodes != null && placeHolderNodes.Count > 0)
                {
                    email.BodyPlaceHolders = new Dictionary<string, string>();
                    foreach (XmlNode placeHodlerNode in placeHolderNodes)
                    {
                        string name = XmlDataUtil.GetAttributeValue(placeHodlerNode, "Name", "");
                        string value = XmlDataUtil.GetAttributeValue(placeHodlerNode, "Value", "");
                        email.BodyPlaceHolders.Add(name, value);
                    }
                }

                return email;
            }
            else
                throw new Exception("Unable to instantiate email: invalid type specified in xml node");
            
        }
    }
}
